//数组
_.chunk(["a", "b", "c", "d"], 2);
// => [['a', 'b'], ['c', 'd']]
_.chunk(["a", "b", "c", "d"], 3);
// => [['a', 'b', 'c'], ['d']]
/********************************************************************************/
_.compact([0, 1, false, 2, "", 3]);
// => [1, 2, 3]
/********************************************************************************/
var array = [1];
var other = _.concat(array, 2, [3], [[4]]);
console.log(other);
// => [1, 2, 3, [4]]
console.log(array);
// => [1]
/********************************************************************************/
_.difference([3, 2, 1], [4, 2]);
// => [3, 1]
/********************************************************************************/
function fn(a) {
  //把每一项过滤一遍再比
  return Math.ceil(a);
}
_.differenceBy([3.1, 2.2, 1.3], [3.4, 1.9], fn);
//2.2
_.differenceBy([{ x: { y: 3 } }, { x: { y: 6 } }], [{ x: { y: 6 } }], "x.y");
//{ 'x': {y:3} }
/********************************************************************************/
var objects = [
  { x: 1, y: 2 },
  { x: 2, y: 1 },
  { x: 2, y: 4 },
];
console.log(
  _.differenceWith(
    objects,
    [
      { x: 1, y: 2 },
      { x: 2, y: 4 },
    ],
    _.isEqual
  )
); //isEqual参数为（objects的每一个**先循环**，第二个参数的每一项）
// => [{ 'x': 2, 'y': 1 }]
/********************************************************************************/
var arr1 = [0, 1, 2, 3, 4, 5, 6];
_.dropRight(arr1, 2); //返回一个从末尾切掉n个的新数组
//[0,1,2,3,4]
/********************************************************************************/
var users = [
  { user: "barney", active: true },
  { user: "fred", active: false },
  { user: "pebbles", active: false },
];
//去除array中从 回调函数返回假值开始到第一个的部分 从右到左
_.dropRightWhile(users, function (o) {
  return !o.active;
});
// => objects for ['barney']

// The `_.matches` iteratee shorthand.
_.dropRightWhile(users, { user: "pebbles", active: false }); //只有最后一个才全部符合数据格式，所有从第二个开始全部返回
// => objects for ['barney', 'fred']

// The `_.matchesProperty` iteratee shorthand.
_.dropRightWhile(users, ["active", false]); //最后一个为false 第二个也是false 所以返回第一个
// => objects for ['barney']

// The `_.property` iteratee shorthand.
_.dropRightWhile(users, "active"); //最后一个就为false 所以从最后一个到第一个全部返回了
// => objects for ['barney', 'fred', 'pebbles']
/********************************************************************************/
//去除array中从 回调函数返回假值开始到第一个的部分 从左到右  同上
_.dropWhile(users, function (o) {
  return !o.active;
});
/********************************************************************************/
var array = [1, 2, 3];
_.fill(array, "a");
console.log(array);
// => ['a', 'a', 'a']
_.fill(Array(3), 2);
// => [2, 2, 2]
_.fill([4, 6, 8, 10], "*", 1, 3); //含头不含尾，10为索引3不包含在内
// => [4, '*', '*', 10]
/********************************************************************************/
var users = [
  { user: "barney", active: false },
  { user: "fred", active: false },
  { user: "pebbles", active: true },
];
_.findIndex(users, function (o) {
  return o.user == "barney";
});
// => 0
// The `_.matches` iteratee shorthand.
_.findIndex(users, { user: "fred", active: false });
// => 1
// The `_.matchesProperty` iteratee shorthand.
_.findIndex(users, ["active", false]);
// => 0
// The `_.property` iteratee shorthand.
_.findIndex(users, "active");
// => 2
/********************************************************************************/
_.findLastIndex(users, function (o) {
  return o.user == "pebbles";
}); //同上 从最后一个开始
/********************************************************************************/
_.head([1, 2, 3]); //返回数组第一个
_.first([1, 2, 3]); //一样
// => 1
/********************************************************************************/
_.indexOf([1, 2, 1, 2], 2);
// => 1
// Search from the `fromIndex`.
_.indexOf([1, 2, 1, 2], 2, 2); //第三个参数开始查询的位置
// => 3
/********************************************************************************/
//获取数组array中除了最后一个元素之外的所有元素 如果是字符串扔返回数组形式
_.initial([1, 2, 3]);
// => [1, 2]
/********************************************************************************/
//创建唯一值的数组，这个数组包含所有给定数组都包含的元素，使用SameValueZero(===)进行相等性比较。（注：可以理解为给定数组的交集）
_.intersection([2, 0], [4, 2], [1, 2]);
// => [2]
/********************************************************************************/
//这个方法类似_.intersection，区别是它接受一个 iteratee 调用每一个arrays的每个值以产生一个值，通过产生的值进行了比较。结果值是从第一数组中选择。iteratee 会传入一个参数：(value)。
_.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
// => [2.1]
// The `_.property` iteratee shorthand.
_.intersectionBy([{ x: 1 }], [{ x: 2 }, { x: 1 }], "x");
// => [{ 'x': 1 }]
/********************************************************************************/
//这个方法类似_.intersection，区别是它接受一个 comparator 调用比较arrays中的元素。结果值是从第一数组中选择。comparator 会传入两个参数：(arrVal, othVal)。
var objects = [
  { x: 1, y: 2 },
  { x: 2, y: 1 },
];
var others = [
  { x: 1, y: 1 },
  { x: 1, y: 2 },
];
_.intersectionWith(objects, others, _.isEqual);
// => [{ 'x': 1, 'y': 2 }]
/********************************************************************************/
_.join(["a", "b", "c"], "~");
// => 'a~b~c'
/********************************************************************************/
_.last([1, 2, 3]);
// => 3
/********************************************************************************/
console.log(_.lastIndexOf([1, 2, 1, 2], 2));
// => 3
// Search from the `fromIndex`.[fromIndex=array.length-1] (number): 开始搜索的索引值
_.lastIndexOf([1, 2, 1, 2], 2, 2);
// => 1
/********************************************************************************/
_.flatten([1, [2, [3, [4]], 5]]);
// => [1, 2, [3, [4]], 5]
/********************************************************************************/
_.flattenDeep([1, [2, [3, [4]], 5]]);
// => [1, 2, 3, 4, 5]
/********************************************************************************/
var array = [1, [2, [3, [4]], 5]];
_.flattenDepth(array, 1);
// => [1, 2, [3, [4]], 5]
_.flattenDepth(array, 2);
// => [1, 2, 3, [4], 5]
/********************************************************************************/
//这个方法返回一个由键值对pairs构成的对象
_.fromPairs([
  ["fred", 30],
  ["barney", 40],
]);
// => { 'fred': 30, 'barney': 40 }
/********************************************************************************/
var array = ["a", "b", "c", "d"];
_.nth(array, 1);
// => 'b'
_.nth(array, -2);
// => 'c';
/********************************************************************************/
//移除数组array中所有和给定值相等的元素,会改变数组，使用SameValueZero 进行全等比较。
var array = [1, 2, 3, 1, 2, 3];
_.pull(array, 2, 3);
console.log(array);
// => [1, 1]
/********************************************************************************/
//这个方法类似_.pull，区别是这个方法接收一个要移除值的数组,会改变数组。
var array = [1, 2, 3, 1, 2, 3];
_.pullAll(array, [2, 3]);
console.log(array);
// => [1, 1]
/********************************************************************************/
//这个方法类似于_.pullAll ，区别是这个方法接受一个 iteratee（迭代函数） 调用 array 和 values的每个值以产生一个值，通过产生的值进行了比较。iteratee 会传入一个参数： (value)。
var array = [
  { x: { y: 1.4 } },
  { x: { y: 3.5 } },
  { x: { y: 5.1 } },
  { x: { y: 5.2 } },
];
_.pullAllBy(array, [{ x: { y: 1.2 } }, { x: { y: 5.5 } }], function (item) {
  return Math.ceil(item.x.y);
}); //把对象里的y上取整后对比
console.log(array);
// => [{ 'x':{y:3.5} }]
var array = [
  { x: { y: 4 } },
  { x: { y: 3 } },
  { x: { y: 5 } },
  { x: { y: 5 } },
];
_.pullAllBy(array, [{ x: { y: 4 } }, { x: { y: 5 } }], "x.y"); //把对象里的y对比
console.log(array);
// => [ {"x": { "y": 3}}
/********************************************************************************/
//这个方法类似于_.pullAll，区别是这个方法接受 comparator 调用array中的元素和values比较。comparator 会传入两个参数：(arrVal, othVal)
var array = [
  { x: 1, y: 2 },
  { x: 3, y: 4 },
  { x: 5, y: 6 },
];
_.pullAllWith(array, [{ x: 3, y: 4 }], _.isEqual);
console.log(array);
// => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
/********************************************************************************/
//根据索引 indexes，移除array中对应的元素，并返回被移除元素的数组。
var array = [5, 10, 15, 20];
var evens = _.pullAt(array, 1, 3);
console.log(array);
// => [5, 15]
console.log(evens);
// => [10, 20]
/********************************************************************************/
//移除数组中predicate（断言）返回为真值的所有元素，并返回移除元素组成的数组。predicate（断言） 会传入3个参数：_.filter不同, 这个方法会改变数组 array。使用_.pull来根据提供的value值从数组中移除元素。
var array = [1, 2, 3, 4];
var evens = _.remove(array, function (n) {
  return n % 2 == 0;
});
console.log(array);
// => [1, 3]
console.log(evens);
// => [2, 4]
/********************************************************************************/
//反转array，使得第一个元素变为最后一个元素，第二个元素变为倒数第二个元素，依次类推。改变原数组
var array = [1, 2, 3];
_.reverse(array);
// => [3, 2, 1]
console.log(array);
// => [3, 2, 1]
/********************************************************************************/
//裁剪数组array，从 start 位置开始到end结束，但不包括 end 本身的位置。这个方法用于代替Array#slice 来确保数组正确返回。
_.slice(array, [(start = 0)], [(end = array.length)]);
/********************************************************************************/
//使用二分法的方式检索来决定 value值 应该插入到数组中 尽可能小的索引位置，以保证array的排序。
var array = ["a", "d"];
console.log(_.sortedIndex(array, "c"));
// => 1
var array = [36, 78];
console.log(_.sortedIndex(array, 50));
// => 1
/********************************************************************************/
//这个方法类似_.sortedIndex ，除了它接受一个 iteratee （迭代函数），调用每一个数组（array）元素，返回结果和value 值比较来计算排序。iteratee 会传入一个参数：(value)。
var objects = [{ x: 4 }, { x: 5 }];
_.sortedIndexBy(objects, { x: 4 }, function (o) {
  return o.x;
});
// => 0
// The `_.property` iteratee shorthand.
_.sortedIndexBy(objects, { x: 4 }, "x");
// => 0
/********************************************************************************/
//这个方法类似_.indexOf，除了它是在已经排序的数组array上执行二分法检索。返回匹配值的索引位置，否则返回 -1
console.log(_.sortedIndexOf([4, 5, 5, 5, 6], 4));
// => 1
console.log(_.sortedIndexOf([4, 5, 5, 5, 6], 11));
// => -1
/********************************************************************************/
//此方法类似于_.sortedIndex，除了 它返回 value值 在 array 中尽可能大的索引位置（index）。
console.log(_.sortedLastIndex([4, 5, 5, 5, 6], 2));
// => 4
/********************************************************************************/
//这个方法类似_.sortedLastIndex ，除了它接受一个 iteratee （迭代函数），调用每一个数组（array）元素，返回结果和value 值比较来计算排序。iteratee 会传入一个参数：(value)。
var objects = [{ x: 4 }, { x: 5 }];
_.sortedLastIndexBy(objects, { x: 4 }, function (o) {
  return o.x;
});
// => 1
// The `_.property` iteratee shorthand.
_.sortedLastIndexBy(objects, { x: 4 }, "x");
// => 1
/********************************************************************************/
//这个方法类似_.lastIndexOf，除了它是在已经排序的数组array上执行二分法检索。
console.log(_.sortedLastIndexOf([4, 1, 5, 1, 4, 5, 4, 5, 4, 5, 6, 7, 4], 5)); //他会默认认为你是排好序的第一次最后一个是4比5小直接返回-1
// => -1
/********************************************************************************/
//这个方法类似_.uniq，除了它会优化排序数组。
console.log(_.sortedUniq([2, 1, 2, 2, 2, 2, 3, 2, 2])); //默认认为你已经是排好序的数组，所以只有相邻的重复才会被去掉
// => [2, 1, 2, 3, 2]
/********************************************************************************/
//这个方法类似_.uniqBy，除了它会优化排序数组。
_.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
// => [1.1, 2.3]
/********************************************************************************/
//获取除了array数组第一个元素以外的全部元素。
_.tail([1, 2, 3]);
// => [2, 3]
/********************************************************************************/
//创建一个数组切片，从array数组的起始元素开始提取n个元素
_.take([1, 2, 3]);
// => [1]
_.take([1, 2, 3], 2);
// => [1, 2]
_.take([1, 2, 3], 5);
// => [1, 2, 3]
_.take([1, 2, 3], 0);
// => []
/********************************************************************************/
//创建一个数组切片，从array数组的最后一个元素开始提取n个元素。
_.takeRight([1, 2, 3]);
// => [3]
_.takeRight([1, 2, 3], 2);
// => [2, 3]
_.takeRight([1, 2, 3], 5);
// => [1, 2, 3]
_.takeRight([1, 2, 3], 0);
// => []
/********************************************************************************/
//从array数组的最后一个元素开始提取元素，直到 predicate 返回假值。predicate 会传入三个参数： (value, index, array)。
var users = [
  { user: "barney", active: true },
  { user: "fred", active: false },
  { user: "pebbles", active: false },
];
_.takeRightWhile(users, function (o) {
  return !o.active;
});
// => objects for ['fred', 'pebbles']
// The `_.matches` iteratee shorthand.
_.takeRightWhile(users, { user: "pebbles", active: false });
// => objects for ['pebbles']
// The `_.matchesProperty` iteratee shorthand.
_.takeRightWhile(users, ["active", false]);
// => objects for ['fred', 'pebbles']
// The `_.property` iteratee shorthand.
_.takeRightWhile(users, "active");
// => []
/********************************************************************************/
//从array数组的起始元素开始提取元素，，直到 predicate 返回假值。predicate 会传入三个参数： (value, index, array)。
var users = [
  { user: "barney", active: false },
  { user: "fred", active: false },
  { user: "pebbles", active: true },
];
_.takeWhile(users, function (o) {
  return !o.active;
});
// => objects for ['barney', 'fred']
// The `_.matches` iteratee shorthand.
_.takeWhile(users, { user: "barney", active: false });
// => objects for ['barney']
// The `_.matchesProperty` iteratee shorthand.
_.takeWhile(users, ["active", false]);
// => objects for ['barney', 'fred']
// The `_.property` iteratee shorthand.
_.takeWhile(users, "active");
// => []
/********************************************************************************/
//创建一个按顺序排列的唯一值的数组。所有给定数组的元素值使用SameValueZero做等值比较。（注： arrays（数组）的并集，按顺序返回，返回数组的元素是唯一的）
console.log(_.union([2, 3], [1, 5], [4, 7, 6]));
// => [2, 1]
/********************************************************************************/
//这个方法类似_.union ，除了它接受一个 iteratee （迭代函数），调用每一个数组（array）的每个元素以产生唯一性计算的标准。iteratee 会传入一个参数：(value)。
_.unionBy([2.1], [1.2, 2.3], Math.floor);
// => [2.1, 1.2]
// The `_.property` iteratee shorthand.
_.unionBy([{ x: 1 }], [{ x: 2 }, { x: 1 }], "x");
// => [{ 'x': 1 }, { 'x': 2 }]
/********************************************************************************/
//这个方法类似_.union， 除了它接受一个 comparator 调用比较arrays数组的每一个元素。 comparator 调用时会传入2个参数： (arrVal, othVal)。
var objects = [
  { x: 1, y: 2 },
  { x: 2, y: 1 },
];
var others = [
  { x: 1, y: 1 },
  { x: 1, y: 2 },
];
_.unionWith(objects, others, _.isEqual);
// => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
/********************************************************************************/
//
var clusters = _.chain([
  { type: "test", value: 1, instance_id: 1 },
  { type: "test", value: 2, instance_id: 2 },
  { type: "pre", value: 3, instance_id: 3 },
  { type: "pre", value: 4, instance_id: 4 },
  { type: "test", value: 5, instance_id: 5 },
])

  .groupBy((cluster) => {
    return cluster.type;
  })
  .mapValues((stage) => {
    return _.mapKeys(stage, (instance) => {
      return instance.instance_id;
    });
  })
  .value();
console.log("clusters", clusters);
console.log(
  "_.mapKeys",
  _.mapKeys([{ type: "test", value: 1, instance_id: 1 }], (instance) => {
    return instance.instance_id;
  })
);
/********************************************************************************/
//
import flatMap from 'lodash/fp/flatMap';

const users = [
  { id: 1, hobbies: ['reading', 'swimming'] },
  { id: 2, hobbies: ['running', 'cycling'] },
  { id: 3, hobbies: ['painting', 'dancing'] }
];

const allHobbies = flatMap(user => user.hobbies)(users);//user => user.hobbies 函数返回的是数组，会被打平一层
console.log(allHobbies);
//['reading', 'swimming', 'running', 'cycling', 'painting', 'dancing']

/********************************************************************************/
//

/********************************************************************************/
//

/********************************************************************************/
//

/********************************************************************************/
//

/********************************************************************************/
//
const isUsedList = (list) => Array.isArray(list) && list.length > 0;
const isNotArray = _.negate(_.isArray);
class SetUtils {
  constructor(draft) {
    this.draft = draft;
  }

  setValue = (key, val) => {
    _.set(this.draft, [key], val);
  };

  getValue = (key) => get(this.draft, key);

  setValues = (obj) => {
    _.assign(this.draft, obj);
  };

  setValueWhenEmpty = (checkFn, key, val) => {
    checkFn(_.get(this.draft, [key])) && this.setValue(key, val);
  };

  setValueWhenNil = _.curry(this.setValueWhenEmpty, 3)(_.isNil);

  setValueWhenNotList = _.curry(this.setValueWhenEmpty, 3)(isNotArray);
  setValueWhenNotUsedList = _.curry(
    this.setValueWhenEmpty,
    3
  )(_.negate(isUsedList));
}

let aa = new SetUtils({ sdf: [] });
aa.setValueWhenNotList("sdf", 345);
console.log("sdfs", aa.draft);

const getChild = (n) => _.get(n, ["children"], []);
getDeepChildProduct = (product) => {
  if (!product) {
    return [];
  }
  const childrenProduct = getChild(product);
  if (!childrenProduct) {
    return [];
  }
  const deepChildProduct = _.map(childrenProduct, getChild);
  return _.concat(childrenProduct, deepChildProduct);
};

let child = {
  id: 1,
  children: [
    { id: 3, children: [{ id: 4 }, { id: 4.4 }, { id: 4.5 }] },
    {
      id: 5,
      children: [
        {
          id: 6,
          children: [
            {
              id: 7,
            },
          ],
        },
        { id: 6.3 },
      ],
    },
  ],
};

let aa3 = getDeepChildProduct(child);
console.log(aa3);


const dataList = [
  { id: 1, partnerTier: "1", businessType: "BU005" },
  { id: 2, partnerTier: "2", businessType: "BU004" },
  { id: 3, partnerTier: "3", businessType: "BU005" },
  { id: 4, partnerTier: "1", businessType: "BU003" },
  { id: 5, partnerTier: "2", businessType: "BU004" }
];

console.log('_.filter(dataList,', _.filter(dataList, ['partnerTier', ['1', '2']]))


